package yunjiao.javatutorials.guava.concurrent.time;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 数据库操作监控
 *
 * @author yangyunjiao
 */
public class DatabaseServiceWithLockMonitoring {
    private final Map<String, String> database = new HashMap<>();
    private final TimeoutMonitoringLock dbLock;

    public DatabaseServiceWithLockMonitoring(long timeoutThreshold) {
        this.dbLock = new TimeoutMonitoringLock(new ReentrantLock(), timeoutThreshold);

        // 初始化一些测试数据
        database.put("user:1", "Alice");
        database.put("user:2", "Bob");
        database.put("user:3", "Charlie");
    }

    /**
     * 模拟数据库查询操作
     */
    public String query(String key) throws InterruptedException {
        dbLock.lock();
        try {
            // 模拟数据库查询延迟
            Thread.sleep(30 + (long)(Math.random() * 50));
            return database.get(key);
        } finally {
            dbLock.unlock();
        }
    }

    /**
     * 模拟数据库更新操作
     */
    public void update(String key, String value) throws InterruptedException {
        dbLock.lock();
        try {
            // 模拟数据库更新延迟（通常比查询慢）
            Thread.sleep(50 + (long)(Math.random() * 100));
            database.put(key, value);
            System.out.println("更新完成: " + key + " = " + value);
        } finally {
            dbLock.unlock();
        }
    }

    /**
     * 批量操作 - 可能耗时较长
     */
    public void batchUpdate(Map<String, String> updates) throws InterruptedException {
        dbLock.lock();
        try {
            System.out.println("开始批量更新，数量: " + updates.size());

            // 模拟批量操作的较长耗时
            Thread.sleep(100 + updates.size() * 20);

            database.putAll(updates);
            System.out.println("批量更新完成");
        } finally {
            dbLock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // 创建数据库服务，设置超时阈值为40ms
        DatabaseServiceWithLockMonitoring dbService =
                new DatabaseServiceWithLockMonitoring(40);

        ExecutorService executor = Executors.newFixedThreadPool(3);

        // 并发查询
        for (int i = 1; i <= 5; i++) {
            final String key = "user:" + i;
            executor.submit(() -> {
                try {
                    String result = dbService.query(key);
                    System.out.println("查询 " + key + " = " + result);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }

        Thread.sleep(1000);

        // 批量更新（可能触发警告）
        Map<String, String> batchData = new HashMap<>();
        for (int i = 10; i < 20; i++) {
            batchData.put("user:" + i, "User" + i);
        }

        executor.submit(() -> {
            try {
                dbService.batchUpdate(batchData);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        executor.shutdown();
        executor.awaitTermination(5, TimeUnit.SECONDS);
    }
}
